package lines.gameengine;

/**
 * Helper class which hold cells of the field
 * @author vpotapenko
 */
public class CellsHolder {

    private Cell[][] cells;

    /**
     * Initialize cells
     *
     * @param width a width of field
     * @param height a height of field
     */
    public void initialize(int width, int height) {
        cells = new Cell[width][height];
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                cells[x][y] = new Cell(x, y);
            }
        }
    }

    /**
     * Clear all existing balls from the field or reinitializing cells if another size
     */
    public void reset(int width, int height) {
        if (cells == null || getWidth() != width || getHeight() != height)
            initialize(width, height);
        else
            clearCells();
    }

    private void clearCells() {
        for (int x = 0; x < getWidth(); x++) {
            for (int y = 0; y < getHeight(); y++) {
                cells[x][y].clear();
            }
        }
    }

    /**
     * Returns number of horizontal cells in the field
     * @return number of horizontal cells in the field
     */
    public int getWidth() {
        return cells.length;
    }

    /**
     * Returns number of vertical cells in the field
     * @return number of vertical cells in the field
     */
    public int getHeight() {
        return getWidth() > 0 ? cells[0].length : 0;
    }

    /**
     * Returns cell by horizontal and vertical coordinates or <code>null</code>
     * if coordinates is invalid
     *
     * @param x horizontal coordinate
     * @param y vertical coordinate
     *
     * @return cell of field or <code>null</code>
     */
    public Cell getCell(int x, int y) {
        return isValidPoint(x, y) ? cells[x][y] : null;
    }

    /**
     * Returns cell by field point or <code>null</code> if point is invalid
     *
     * @param point point of the cell
     * @return cell by field point or <code>null</code>
     */
    public Cell getCell(FieldPoint point) {
        return isValidPoint(point.getX(), point.getY()) ? cells[point.getX()][point.getY()] : null;
    }

    /**
     * Returns <code>true</code> is valid field point
     *
     * @param x horizontal coordinate
     * @param y vertical coordinate
     *
     * @return <code>true</code> is valid field point 
     */
    public boolean isValidPoint(int x, int y) {
        return 0 <= x && x < getWidth()
                && 0 <= y && y < getHeight();
    }
}
